package com.gitee.cui.http.netty.echo;

import com.alibaba.fastjson.JSONObject;
import com.gitee.cui.http.HttpProtocolHelper;
import com.gitee.cui.util.JsonUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.MixedAttribute;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Http请求回显处理类
 * @author cuiqingqiang
 * @version 1.0
 * @date 2021/10/28 16:12
 **/
public class HttpEchoHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest request) throws Exception {
        if (!request.decoderResult().isSuccess()) {
            HttpProtocolHelper.sendError(ctx, HttpResponseStatus.BAD_REQUEST);
            return;
        }
        // 缓存Http协议的版本号
        HttpProtocolHelper.cacheHttpProtocol(ctx, request);
        Map<String, Object> echoMap = new HashMap<>();
        // 1、URI
        String uri = request.uri();
        echoMap.put("request uri", uri);
        // 2、获取请求方法
        HttpMethod method = request.method();
        echoMap.put("request method", method.toString());
        // 3、获取请求头
        HttpHeaders headers = request.headers();
        Map<String, Object> echoHeaders = new HashMap<>();
        for (Map.Entry<String, String> next : headers.entries()) {
            echoHeaders.put(next.getKey(), next.getValue());
        }
        echoMap.put("request headers", echoHeaders);

        // 4、获取uri上的请求参数
        Map<String, String> uriData = paramsFromUri(request);
        echoMap.put("paramsFromUri", uriData);

        // 处理post请求，如果是post请求的话
        if (HttpMethod.POST.equals(request.method())) {
            Map<String, Object> postData = dataFromPost(request);
            echoMap.put("dataFromPost", postData);
        }

        // 回显内容转换为json字符串
        String content = JsonUtil.pojoToJson(echoMap);
        // 发送回显内容到客户端
        HttpProtocolHelper.sendJsonContent(ctx, content);
    }

    /**
     * 从post请求中解析请求体
     * @param request 请求信息
     * @return 请求体信息
     */
    private Map<String, Object> dataFromPost(FullHttpRequest request) {
        Map<String, Object> postData = new HashMap<>();
        String contentType = request.headers().get("Content-Type").trim();
        if (contentType.contains("application/x-www-form-urlencoded") || contentType.contains("multipart/form-data")) {
            postData = fromBodyDecode(request);
        } else if (contentType.contains("application/json")) {
            postData = jsonBodyDecode(request);
        } else if (contentType.contains("text/plain")) {
            ByteBuf content = request.content();
            byte[] bytes = new byte[content.readableBytes()];
            content.readBytes(bytes);
            String text = new String(bytes, StandardCharsets.UTF_8);
            postData.put("text", text);
        }

        return postData;
    }

    /**
     * 解析json个是的请求体
     * @param request 请求信息
     * @return 请求体
     */
    private Map<String, Object> jsonBodyDecode(FullHttpRequest request) {
        Map<String, Object> params = new HashMap<>();
        ByteBuf content = request.content();
        byte[] bytes = new byte[content.readableBytes()];
        content.readBytes(bytes);
        String json = new String(bytes, StandardCharsets.UTF_8);
        JSONObject jsonObject = JsonUtil.jsonToPojo(json, JSONObject.class);
        for (String key : jsonObject.keySet()) {
            params.put(key, jsonObject.get(key));
        }
        return params;
    }

    /**
     * 从post的body中解析请求体
     * @param request 请求信息
     * @return 请求体
     */
    private Map<String, Object> fromBodyDecode(FullHttpRequest request) {
        Map<String, Object> params = new HashMap<>();
        try {
            HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(
                    new DefaultHttpDataFactory(DefaultHttpDataFactory.MINSIZE), request, StandardCharsets.UTF_8);
            List<InterfaceHttpData> postData = decoder.getBodyHttpDatas();
            if (CollectionUtils.isEmpty(postData) && request.content().isReadable()) {
                String body = request.content().toString(StandardCharsets.UTF_8);
                params.put("body", body);
            }

            for (InterfaceHttpData data : postData) {
                if (InterfaceHttpData.HttpDataType.Attribute == data.getHttpDataType()) {
                    MixedAttribute attribute = (MixedAttribute) data;
                    params.put(attribute.getName(), attribute.getValue());
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return params;
    }

    /**
     * 获取uri上的请求参数数据
     * @param request 请求信息
     * @return 请求参数映射关系
     */
    private Map<String, String> paramsFromUri(FullHttpRequest request) {
        Map<String, String> uriParams = new HashMap<>();
        QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
        Map<String, List<String>> parameters = decoder.parameters();
        for (Map.Entry<String, List<String>> next : parameters.entrySet()) {
            uriParams.put(next.getKey(), next.getValue().get(0));
        }
        return uriParams;
    }
}
